local handler = require "handler"
local util = require "util"
local reason = require "reason"
local error_code = require "error_code"
local constant = require "constant"
local cjson = require "cjson"

local table_insert = table.insert
local table_sort = table.sort
local math_floor = math.floor

local notify_money_changed = handler.notify_money_changed
local add_awards = handler.add_awards

local SYSTEM_SEQ_LIMIT = 2000000000

local mail_get_sender_map = {}

local function translate_rank_mail(uid,mail_info,mail_cfg)
    local result_content = mail_cfg.content
    local temp_repl = {rand = mail_info.param1}
    return result_content:gsub('{(.-)}',temp_repl)
end

local MAIL_TYPE_RANK = 102
mail_get_sender_map[MAIL_TYPE_RANK] = translate_rank_mail

function get_sender_content(uid,mail_info,mail_template)
    local mail_id = mail_info.mail_id
	local mail_cfg = mail_template[mail_id]
	if not mail_cfg then
		errlog(uid,'get_sender_content failed with mail_id at normal mail',mail_id)
		return
	end
	local hand_func = mail_get_sender_map[mail_id]
	local content = mail_cfg.content
	if hand_func then
		content = hand_func(uid,mail_info,mail_cfg)
	end
    local temp_repl = {rand = mail_info.intp1}
	return mail_cfg.title,content
end

local mail_handler = {}
local function fill_rsp_attach_list(rsp_attach_list,attach_list)
    if attach_list then
        for _,attach_info in pairs(attach_list) do
            local one_attach = {}
            one_attach.id = attach_info.id
            one_attach.count = attach_info.count
            table_insert(rsp_attach_list, one_attach)
        end
    end
end

function mail_handler.REQ_MAIL_LIST(msg)
    --添加一封邮件
    --[[local attach_list1 = {}
    attach_list1[10001] = 1
    attach_list1[10002] = 2
    player:add_mail(102,10,nil,attach_list1)]]

    local uid = player.uid
    local user_data = player.user_data
    local mail_info = user_data.mail_info
    local mail_list = mail_info.mail_list

    local mail_template = global_configs.mail_template
    
    local rsp_mail_list = {}
    local time_secs = util.get_now_time()
    --加载系统普通邮件
    for seq,mail_obj in pairs(mail_list) do
        if time_secs - mail_obj.send_time > 30 * 86400 then --超过一个月的邮件删除
            mail_list:delete_from_hash(seq)
        else
            local one_mail = {}
            local title,content = get_sender_content(uid,mail_obj,mail_template)

            one_mail.mail_seq = mail_obj.mail_seq
            one_mail.title = title
            one_mail.content = content
            one_mail.send_time = mail_obj.send_time
            one_mail.send_user = mail_obj.send_user
            one_mail.read_state    = mail_obj.read_state
            one_mail.receive_state = mail_obj.receive_state

            local attach_list = {}
            fill_rsp_attach_list(attach_list,mail_obj.attach_list)
            one_mail.attach_list = attach_list
            table_insert(rsp_mail_list, one_mail)
        end
    end

    local ok,platform_mail_list = R().mailsvr(1):call('.msg_handler','select_mail_list',uid)

    print("REQ_MAIL_LIST===============",tostring_r(platform_mail_list))
    if ok then
        for seq,mail_obj in pairs(platform_mail_list) do
            table_insert(rsp_mail_list,mail_obj)
        end
    end
    send_to_gateway('mail.RSP_MAIL_LIST', {mail_list = rsp_mail_list})

    return true
end

function mail_handler.REQ_TAKE_ATTACH(msg)
    local uid = player.uid
    local user_data = player.user_data
    local mail_seq = msg.mail_seq

    local mail_info = user_data.mail_info
    local mail_list = mail_info.mail_list

    local rsp_attach_list = {}
    if mail_seq <= SYSTEM_SEQ_LIMIT then
        local mail_obj = mail_list[tostring(mail_seq)]
        if not mail_obj then
            errlog(uid,"mail is not exist",mail_seq)
            return
        end
        local attach_list = mail_obj.attach_list
        if not attach_list then
            errlog("attach is nil",uid)
            return
        end
        fill_rsp_attach_list(rsp_attach_list,attach_list)

        --删除邮件
        mail_list:delete_from_hash(tostring(mail_seq))
    elseif mail_seq > SYSTEM_SEQ_LIMIT then
    --如果是平台邮件需要到邮件服务器去处理
        --local ok,ret,attach_list = skynet.call('.forwarder','lua','TOMAILSVR','take_attach',uid,mail_seq)
        local ok,attach_list = R().mailsvr(1):call('.msg_handler','take_attach',uid,mail_seq)
        if not ok then
            errlog(uid,'failed to fetch user data',ret)
            return
        end
        fill_rsp_attach_list(rsp_attach_list,attach_list)
    end

    -- 发放奖励
    if #rsp_attach_list > 0 then
        local award_reason = reason.TAKE_MAIL_ATTACH
        local chged = add_awards(uid,rsp_attach_list,award_reason)
        if not chged then
            errlog("failed to add_awards",tostring_r(rsp_attach_list))
            send_to_gateway('daily.RSP_SIGNIN',{result = -3})
            return
        end
        notify_money_changed(uid,chged)
    end

    local rsp = {
        attach_list = rsp_attach_list,
        mail_seq = mail_seq
    }    
    send_to_gateway('mail.RSP_TAKE_ATTACH',rsp)
    return true
end

function mail_handler.REQ_DEL_MAIL(msg)
    local uid = player.uid
    local user_data = player.user_data
    local mail_seq = msg.mail_seq

    local mail_info = user_data.mail_info
    local mail_list = mail_info.mail_list

    if mail_seq <= SYSTEM_SEQ_LIMIT then
        if not mail_list[tostring(mail_seq)] then
            errlog("this mail is not exit",uid)
            return 
        end
        mail_list:delete_from_hash(tostring(mail_seq))
    elseif mail_seq > SYSTEM_SEQ_LIMIT then
    --如果是平台邮件需要到邮件服务器去处理    
        --local ok,ret,seq = skynet.call('.forwarder','lua','TOMAILSVR','del_mail',uid,mail_seq)
        local ok,seq = R().mailsvr(1):call('.msg_handler','del_mail',uid,mail_seq)
        if not ok then
            errlog(uid,'failed to del_mail',ret)
            return
        end
    end
    local rsp = {
        mail_seq = mail_seq
    }
    send_to_gateway("mail.RSP_DEL_MAIL",rsp)
    return true
end

function mail_handler.REQ_ALL_MAIL_ATTACH(msg)
    local uid = player.uid
    local user_data = player.user_data
    
    local mail_info = user_data.mail_info
    local mail_list = mail_info.mail_list
    local rsp_attach_list = {}
    --先领取系统内有附件的邮件
    for seq,mail_obj in pairs(mail_list) do
        if mail_obj.attach_list then
            local mail_attach_info = {}
            mail_attach_info.mail_seq = seq
            local one_attach_list = {}
            fill_rsp_attach_list(one_attach_list,mail_obj.attach_list)
            mail_attach_info.attach_list = one_attach_list
            table_insert(rsp_attach_list,mail_attach_info)
            --领完附件即删除
            mail_list:delete_from_hash(tostring(seq))
        end
    end
    --领取平台上有附件的邮件
    --local ok,ret,platform_attach_list = skynet.call('.forwarder','lua','TOMAILSVR','take_all_attach',uid)
    local ok,platform_attach_list = R().mailsvr(1):call('.msg_handler','take_all_attach',uid)
    if ok then
        for k,v in pairs(platform_attach_list) do 
            table_insert(rsp_attach_list,v)
        end
    end

    -- 发放奖励
    local rsp_chged = {}
    for _,obj in pairs(rsp_attach_list) do
        local award_reason = reason.TAKE_MAIL_ATTACH
        local chged = add_awards(uid,obj.attach_list,award_reason)
        if not chged then
            errlog("failed to add_awards",tostring_r(obj.attach_list))
            send_to_gateway('daily.RSP_SIGNIN',{result = -3})
            return
        end
        rsp_chged.coins = chged.coins or rsp_chged.coins
        rsp_chged.gems = chged.gems or rsp_chged.gems
        rsp_chged.roomcards = chged.roomcards or rsp_chged.roomcards 
    end
    notify_money_changed(uid,rsp_chged)
    local rsp = {
        mail_attach_list = rsp_attach_list
    }
    send_to_gateway("mail.RSP_ALL_MAIL_ATTACH",rsp)
    return true
end

function mail_handler.REQ_READ_MAIL(msg)
    local uid = player.uid
    local user_data = player.user_data
    local mail_seq = msg.mail_seq

    local mail_info = user_data.mail_info
    local mail_list = mail_info.mail_list

    local rsp_attach_list = {}
    if mail_seq <= SYSTEM_SEQ_LIMIT then
        local mail_obj = mail_list[tostring(mail_seq)]
        if not mail_obj then
            errlog(uid,"mail is not exist",mail_seq)
            return
        end

        mail_obj.read = true
    elseif mail_seq > SYSTEM_SEQ_LIMIT then
        --如果是平台邮件需要到邮件服务器去处理
        local ok,succ = R().mailsvr(1):call('.msg_handler','make_read',uid,mail_seq)
        if not ok then
            errlog(uid,'failed to mark read mail',mail_seq)
            return
        end
    end

    send_to_gateway('mail.RSP_READ_MAIL',{mail_seq = mail_seq})

    return true
end

function mail_handler.notify_new_mail(count)
    send_to_gateway("mail.NTF_NEW_MAIL",{ count = count })
end

handler.register_module_handlers('mail',mail_handler)